<script setup>
import { ref, watch } from 'vue'
import { ElMessage, ElImageViewer } from 'element-plus'
import { UploadFilled } from '@element-plus/icons-vue'
import { uploadApi } from '@/api'
import { useI18n } from 'vue-i18n'

const { t } = useI18n({ useScope: 'global' })

const props = defineProps({
  modelValue: {
    required: true,
    type: String
  },
  limit: {
    type: Number,
    default: 1
  },
  size: {
    type: Number,
    default: 2
  },
  accept: {
    type: String,
    default: '.jpg,.jpeg,.png'
  }
})

const emits = defineEmits(['update:modelValue'])

const fileList = ref([])

function updateModelValue() {
  emits('update:modelValue', fileList.value.map(file => file.url).toString())
}

watch(
  () => props.modelValue,
  urls => {
    fileList.value = urls
      ? urls
          .split(',')
          .map((url, index) =>
            normalFile(url, `${t('global.file')} - ${index + 1}`)
          )
      : []
  },
  { immediate: true }
)

async function handleUpload(req) {
  await beforeUpload(req.file)
  // TODO 调接口
  const formData = new FormData()
  formData.append('file', req.file)
  const { data } = await uploadApi.uploadImage(formData)

  fileList.value.pop() // 删除el-element-plus默认的rawFile
  fileList.value.push(normalFile(data, data))
  updateModelValue()
}

function normalFile(url, name) {
  return {
    url,
    name
  }
}

async function beforeUpload(rawFile) {
  const { name, size, type } = rawFile
  let errorMessage
  const userFileSize = size / 1024 / 1024
  // 校验个数
  if (fileList.value.length - 1 >= props.limit) {
    errorMessage = t('global.validUploadLimit', {
      limit: props.limit,
      uploadedLength: fileList.value.length - 1
    })
  }
  // 校验尺寸
  else if (userFileSize > props.size) {
    errorMessage = t('global.vaildUploadSize', {
      size: props.size,
      userSize: userFileSize.toFixed(3)
    })
  }
  // 校验类型
  else if (!type.startsWith('image')) {
    errorMessage = t('global.vaildUploadType')
  }
  if (errorMessage) {
    ElMessage.warning(errorMessage)
    return Promise.reject(errorMessage)
  }
}

async function beforeRemove(uploadFile) {
  const { status, url } = uploadFile
  if (status === 'ready' || !url) return false
  // 目前的方案是删除不调接口
}

async function handleRemove() {
  updateModelValue()
}

const images = ref([])
const handlePreview = async ({ url }) => {
  images.value = [url]
}
</script>

<template>
  <div class="w-full">
    <el-upload
      class="w-full"
      v-bind="$attrs"
      v-model:file-list="fileList"
      action="#"
      drag
      :http-request="handleUpload"
      :accept="props.accept"
      :before-remove="beforeRemove"
      :on-remove="handleRemove"
      :on-preview="handlePreview"
    >
      <el-icon class="el-icon--upload"><upload-filled /></el-icon>
      <div class="el-upload__text">
        {{ t('global.dargFileHereOr') }}
        <em>{{ t('global.clickToUpload') }}</em>
      </div>
      <template #tip>
        <div class="el-upload__tip">
          {{ t('global.uploadTip', { size: props.size, type: props.accept }) }}
        </div>
      </template>
    </el-upload>

    <ElImageViewer
      v-if="images.length"
      :url-list="images"
      @close="images.pop()"
      hide-on-click-modal
    />
  </div>
</template>
